package com.tanjun.mallservice.web.service.impl;

import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.tanjun.data.components.CloudCacheManager;
import com.tanjun.mallservice.web.orm.entity.MallPluSkuPrice;
import com.tanjun.mallservice.web.orm.mapper.MallPluSkuPriceMapper;
import com.tanjun.mallservice.web.service.MallPluSkuPriceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author jjtan
 * @description 针对表【mall_plu_sku_price(商品价格信息)】的数据库操作Service实现
 * @createDate 2024-03-21 14:42:17
 */
@Service
public class MallPluSkuPriceServiceImpl extends ServiceImpl<MallPluSkuPriceMapper, MallPluSkuPrice>
        implements MallPluSkuPriceService {
    @Autowired
    private CloudCacheManager cacheManager;

    private static final String GET_PRICE_CACHE = "getPluPrice:";

    /**
     * 根据商品id获取价格信息
     *
     * @param pluId 商品id
     * @return 价格信息列表
     */
    @Override
    public List<MallPluSkuPrice> getPriceListByPluId(Long pluId) {
        if (cacheManager.hasKey(GET_PRICE_CACHE + pluId)) {
            return cacheManager.getValue(GET_PRICE_CACHE + pluId, List.class);
        }
        LocalDateTime now = LocalDateTime.now();
        List<MallPluSkuPrice> listPrice = this.list(QueryChain.of(MallPluSkuPrice.class)
                .le(MallPluSkuPrice::getBeginTime, now)
                .ge(MallPluSkuPrice::getEndTime, now)
                .eq(MallPluSkuPrice::getPluId, pluId)
        );

        if (!CollectionUtils.isEmpty(listPrice)) {
            Map<Long, List<MallPluSkuPrice>> map = listPrice.stream()
                    .collect(Collectors.groupingBy(MallPluSkuPrice::getSkuId));
            List<MallPluSkuPrice> listRe = new ArrayList<>();
            map.forEach((k, v) -> {
                if (v.size() == 1) {
                    listRe.add(v.get(0));
                } else { //如果存在多条重复的价格，按照开始时间最晚的
                    listRe.add(v.stream()
                            .sorted((t1, t2) -> t1.getBeginTime().isBefore(t2.getBeginTime()) ? 1 : -1)
                            .findFirst().get()
                    );
                }
            });
            //获取最小时间
            LocalDateTime minEndTime = listRe.stream()
                    .sorted((t1, t2) -> t1.getEndTime().isBefore(t2.getEndTime()) ? -1 : 1)
                    .findFirst().get().getEndTime();
            LocalDateTime minBeginTime = getNextBeginTime(now, pluId);
            long seconds = Duration.between(now, minBeginTime != null && minBeginTime.isBefore(minEndTime) ?
                    minBeginTime : minEndTime).getSeconds();
            if (seconds > 3) {
                cacheManager.saveValue(GET_PRICE_CACHE + pluId, listRe, Duration.between(now, minEndTime).getSeconds());
            }
        }
        return Collections.emptyList();
    }

    /**
     * 获取接下来最下之后最小的 一个开始时间
     *
     * @param dateTime
     * @param pluId
     * @return
     */
    @Override
    public LocalDateTime getNextBeginTime(LocalDateTime dateTime, Long pluId) {
        return this.list(QueryChain.of(MallPluSkuPrice.class)
                        .select(MallPluSkuPrice::getBeginTime)
                        .eq(MallPluSkuPrice::getPluId, pluId)
                        .ge(MallPluSkuPrice::getBeginTime, dateTime)
                        .orderBy(MallPluSkuPrice::getBeginTime, true)
                ).stream().map(MallPluSkuPrice::getBeginTime).findFirst()
                .orElse(null);
    }


    private void clearCache(Long pluId) {
        cacheManager.delKeys(GET_PRICE_CACHE + pluId);
    }
}




